#include "material_texture.h"
#include <fstream>
#include <iostream>

TextureMaterial::TextureMaterial(Scene *scene) : SolidMaterial(scene), m_image(0)
{
  std::cout << "Texture Material Created" << std::endl;
}

TextureMaterial::~TextureMaterial()
{
  if (m_image)
    delete[] m_image;
}

Color TextureMaterial::m_getColor(Collision c)
{
  double u = c.u * m_repeat,
         v = c.v * m_repeat;
  u -= (int)u;
  v -= (int)v;
  if (u < 0)
  {
    u = 1 + u;
  }
  if (v < 0)
  {
    v = 1 + v;
  }
  u *= m_width;
  v *= m_height;

  Color uC = m_interpolate(u, (int)u, (int)v, 1, 0),
        uV = m_interpolate(v, (int)u, (int)v, 0, 1);

  uC *= 0.5;
  uV *= 0.5;
  return uC + uV;
}
Color TextureMaterial::m_interpolate(double percent, unsigned int u, unsigned int v, 
                    unsigned int a, unsigned int b)
{
  percent -= (int)percent;
  Color colorA = m_image[u + v * m_width],
        colorB = m_image[(u + a)%m_width + ((v + b)%m_height) * m_width];
  colorA *= (1 - percent);
  colorB *= percent;

  colorA += colorB;
  return colorA;
}

void TextureMaterial::loadAttributes(std::istream &inData)
{
  std::string filename;
  inData >> filename >> m_repeat;
  SolidMaterial::loadAttributes(inData);

  std::ifstream texDataFile(filename.c_str());
  CommentStream texData(texDataFile);


  std::string header;
  texData >> header;

  if (header != "P3")
  {
    return;
  }

  texData >> m_width >> m_height;

  double maxColor;
  texData >> maxColor;

  m_image = new Color[m_width * m_height];
  if (!m_image)
  {
    std::cerr << "Error loading texture" << std::endl;
  }

  for (int x = 0; x < m_width; x++)
  {
    for (int y = 0; y < m_height; y++)
    {
      Color &c = m_image[x + y * m_width];
      texData >> c.r >> c.g >> c.b;
      c *= 1 / maxColor;
    }
  }
}
